#if 0

#include <ros/ros.h>
#include <chrono> // 用于高精度计时
#include <iostream>
#include <string>
#include <ros/protobuffer_traits.h>
#include <ros/serialization_protobuffer.h>
// 包含你的 Protobuf 消息头文件
#include "publish_info.pb.h"

// 消息回调函数const ros::MessageEvent<pbtest::PublishInfo>
void messageCallback(const ros::MessageEvent<pbtest::PublishInfo>& received_msg) {
    // --- 开始计时反序列化 ---
    auto start = std::chrono::high_resolution_clock::now();

    // 当 ROS 调用你的回调函数时，消息已经反序列化
    // 到 'received_msg' 对象中。因此，简单地访问它就是反序列化的“结束”。
    // 如果你的设置涉及到接收原始字节（例如 std_msgs::ByteMultiArray）
    // 然后在回调中手动调用 'ParseFromString'，那么计时将围绕该调用进行。

    // 为了确保对象被完全访问/实例化，你可以执行一个简单的操作
    // 对于 Protobuf，某些字段的解析可能是懒惰的，但主对象是准备好的。
    // 访问一个字段确保它被“使用”并可能完全反序列化。
    // std::string name = received_msg.getMessage()->name(); // 访问一个字段以确保反序列化完成（如果是懒惰的）
    std::string name = received_msg.getMessage()->DebugString(); // 访问一个字段以确保反序列化完成（如果是懒惰的）

    auto end = std::chrono::high_resolution_clock::now();
    // --- 结束计时反序列化 ---

    std::chrono::nanoseconds duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);
    std::cout << "反序列化时间 (回调函数开始到访问数据): " << duration.count() << " 纳秒" << std::endl;
    // std::cout << "  接收到: " << received_msg->name() << " - " << received_msg->num() << std::endl;
}

int main(int argc, char** argv) {
    ros::init(argc, argv, "pb_subscriber_node");
    ros::NodeHandle nh;

    // 订阅话题，使用你兼容 Protobuf 的 ROS 消息类型
    ros::Subscriber sub = nh.subscribe("/my_protobuf_topic", 1000, messageCallback); // 队列大小 10

    ros::spin(); // 保持节点运行

    return 0;
}

#endif 

#if 1
#include <ros/ros.h>
#include <chrono> // For high-resolution timing
#include <iostream>
#include <string>
#include <vector> // To store deserialization times
#include <numeric> // For std::accumulate
#include <cmath>   // For std::sqrt (if you want standard deviation)

#include <ros/protobuffer_traits.h>
#include <ros/serialization_protobuffer.h>

// Include your Protobuf message header
#include "publish_info.pb.h"

std::vector<long long> deserialization_times_ns;
std::mutex g_mutex; 

#define DESERIALIZATION_COUNT_THRESHOLD 1000 // Collect 1000 samples

// Message callback function
void messageCallback(const ros::MessageEvent<pbtest::PublishInfo>& received_msg) {
    // --- Start Timing Deserialization ---
    auto start = std::chrono::high_resolution_clock::now();

    std::string debug_str = received_msg.getMessage()->DebugString();

    auto end = std::chrono::high_resolution_clock::now();
    // --- End Timing Deserialization ---

    std::chrono::nanoseconds duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start);

    // Protect access to the shared vector
    // std::lock_guard<std::mutex> lock(g_mutex); // Only needed if spin() is not used or if multiple threads access it
    deserialization_times_ns.push_back(duration.count());

    // Optional: Print real-time feedback
    // std::cout << "反序列化时间 (回调函数开始到访问数据): " << duration.count() << " 纳秒" << std::endl;

    // Check if we've collected enough samples and then shutdown to print results
    if (DESERIALIZATION_COUNT_THRESHOLD > 0 && deserialization_times_ns.size() >= DESERIALIZATION_COUNT_THRESHOLD) {
        ROS_INFO("Collected %d deserialization samples. Shutting down to print results.", DESERIALIZATION_COUNT_THRESHOLD);
        ros::shutdown(); // Trigger shutdown to exit ros::spin()
    }
}

int main(int argc, char** argv) {
    ros::init(argc, argv, "pb_subscriber_node");
    ros::NodeHandle nh;

    // Subscribe to the topic using your Protobuf-compatible ROS message type
    ros::Subscriber sub = nh.subscribe("/my_protobuf_topic", 1000, messageCallback); // Queue size 1000

    ROS_INFO("Subscriber node started. Waiting for messages...");
    if (DESERIALIZATION_COUNT_THRESHOLD > 0) {
        ROS_INFO("Will collect %d deserialization samples then print average.", DESERIALIZATION_COUNT_THRESHOLD);
    } else {
        ROS_INFO("Will collect deserialization samples indefinitely. Press Ctrl+C to stop and print average.");
    }

    ros::spin(); // Keep node alive until ros::shutdown() is called or Ctrl+C

    // --- Statistics calculation after ros::spin() exits ---
    if (!deserialization_times_ns.empty()) {
        long long total_duration_ns = 0;
        for (long long time_ns : deserialization_times_ns) {
            total_duration_ns += time_ns;
        }
        
        // Using std::accumulate for sum (requires <numeric>)
        // long long total_duration_ns = std::accumulate(deserialization_times_ns.begin(), deserialization_times_ns.end(), 0LL);


        double average_duration_ns = static_cast<double>(total_duration_ns) / deserialization_times_ns.size();
        double average_duration_us = average_duration_ns / 1000.0; // Convert to microseconds
        double average_duration_ms = average_duration_us / 1000.0; // Convert to milliseconds

        std::cout << "\n--- 反序列化性能测试结果 ---" << std::endl;
        std::cout << "总反序列化次数: " << deserialization_times_ns.size() << std::endl;
        std::cout << "总耗时: " << total_duration_ns / 1e9 << " 秒 (" << total_duration_ns << " 纳秒)" << std::endl;
        std::cout << "平均每次反序列化耗时: " << average_duration_ns << " 纳秒" << std::endl;
        std::cout << "平均每次反序列化耗时: " << average_duration_us << " 微秒" << std::endl;
        std::cout << "平均每次反序列化耗时: " << average_duration_ms << " 毫秒" << std::endl;

        // Optionally, calculate standard deviation for more robust analysis
        if (deserialization_times_ns.size() > 1) {
            double sum_sq_diff = 0.0;
            for (long long time_ns : deserialization_times_ns) {
                sum_sq_diff += std::pow(time_ns - average_duration_ns, 2);
            }
            double variance = sum_sq_diff / deserialization_times_ns.size();
            double std_dev_ns = std::sqrt(variance);
            std::cout << "标准差: " << std_dev_ns << " 纳秒" << std::endl;
        }
    } else {
        std::cout << "没有接收到任何消息进行反序列化测试。" << std::endl;
    }

    return 0;
}
#endif